package com.ocom.exposeapi.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.HttpUtils;
import com.ocom.common.constant.ExposeApiUrl;
import com.ocom.common.entity.company.EntityComDockApi;
import com.ocom.common.enums.DockApiCodeEnum;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.company.GetComRequestRequest;
import com.ocom.common.request.company.GetReplyApiParaRequest;
import com.ocom.common.request.exposeapi.ssgl.*;
import com.ocom.common.request.simple.ssgl.SSGLAccessRecordRequest;
import com.ocom.common.request.simple.ssgl.SSGLNewPersonInfoRequest;
import com.ocom.common.request.srvpaccess.SendAccessRecordRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.response.GetComRequestResponse;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.utils.SignUtils;
import com.ocom.common.utils.ssgl.SSGLReturnDto;
import com.ocom.common.vo.human.UserInfoVo;
import com.ocom.common.vo.pyhandle.GetComWhiteListVo;
import com.ocom.exposeapi.feign.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/*
 * 宿管系统
 * * */
@Slf4j
@RestController
public class SSGLController {

    @Autowired
    private CompanyClientService companyClientService;
    @Autowired
    private PayConfigClientService payConfigClientService;
    @Autowired
    private HumanFeignService humanFeignService;
    @Autowired
    private AccessService accessService;
    @Autowired
    private PayHandleClientService payHandleClientService;
    @Autowired
    private MjrecodeClientService mjrecodeClientService;

    @PostMapping(ExposeApiUrl.URL_ExposeApi_SsglGetPersonVer)
    public Result getPersonVer(@Validated @RequestBody GetPersonVerRequest request) {
        SSGLReturnDto returnDto = new SSGLReturnDto();
        checkSign(request, request.getSvrId(), request.getComAppid(), DockApiCodeEnum.ssgl_getpersonver.getValue(), request.getSign(), returnDto);
        if (null == returnDto.getEntityComDockApi() || null != returnDto.getResultEnum()) {
            return ResultUtil.error(returnDto.getResultEnum());
        }
        Result result = payConfigClientService.getXFWhiteVer(returnDto.getEntityComDockApi().getComId());
        if (200 != result.getCode() || null == result.getData()) {
            return ResultUtil.error(ResultEnum.Err_1000);
        }
        return result;
    }




    @PostMapping(ExposeApiUrl.URL_ExposeApi_SsglSetPersonVer)
    public Result setPersonVer(@Validated @RequestBody SetPersonVerRequest request) {
        SSGLReturnDto returnDto = new SSGLReturnDto();
        checkSign(request, request.getSvrId(), request.getComAppid(), DockApiCodeEnum.ssgl_getpersonver.getValue(), request.getSign(), returnDto);
        if (null != returnDto.getResultEnum()) {
            return ResultUtil.error(returnDto.getResultEnum());
        }
        Result result = companyClientService.getApiPara(returnDto.getEntityComDockApi().getComId(), returnDto.getEntityComDockApi().getDockApiCode());
        if (200 != result.getCode()) {
            return ResultUtil.error(ResultEnum.Err_1000);
        }
        EntityComDockApi getApiPara = JSON.parseObject(JSON.toJSONString(result.getData()), EntityComDockApi.class);
        StringBuilder apiPara = new StringBuilder();

        if (StringUtils.isNotBlank(getApiPara.getApiPara())) {
            try {
                Map<String, Object> map = JSON.parseObject(getApiPara.getApiPara(), HashMap.class);
                map.put("personVer", request.getPersonVer());
                apiPara.append(JSON.toJSONString(map));
            } catch (Exception e) {
                e.printStackTrace();
                initApiPara(apiPara, request.getPersonVer());
            }

        } else {
            initApiPara(apiPara, request.getPersonVer());
        }

        companyClientService.setApiPara(returnDto.getEntityComDockApi().getComId(), returnDto.getEntityComDockApi().getDockApiCode(), apiPara.toString());

        return ResultUtil.success(request.getPersonVer());
    }


    @PostMapping(ExposeApiUrl.URL_ExposeApi_SsglDeptInfo)
    public Result deptInfo(@Validated @RequestBody DeptInfoRequest request) {
        SSGLReturnDto returnDto = new SSGLReturnDto();
        checkSign(request, request.getSvrId(), request.getComAppid(), DockApiCodeEnum.ssgl_deptInfo.getValue(), request.getSign(), returnDto);
        if (null != returnDto.getResultEnum()) {
            return ResultUtil.error(returnDto.getResultEnum());
        }
        Result result = humanFeignService.GetDeptInfo(returnDto.getEntityComDockApi().getComId(), null, null);
        if (200 != result.getCode() || null == result.getData()) {
            return ResultUtil.error(ResultEnum.Err_1000);
        }
        return result;
    }


    @PostMapping(ExposeApiUrl.URL_ExposeApi_SsglAllPersonInfo)
    public Result allPersonInfo(@Validated @RequestBody AllPersonInfoRequest request) {
        SSGLReturnDto returnDto = new SSGLReturnDto();
        checkSign(request, request.getSvrId(), request.getComAppid(), DockApiCodeEnum.ssgl_allPersonInfo.getValue(), request.getSign(), returnDto);
        if (null != returnDto.getResultEnum()) {
            return ResultUtil.error(returnDto.getResultEnum());
        }
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setComId(returnDto.getEntityComDockApi().getComId());
        userInfoVo.setPage(request.getIndex());
        userInfoVo.setSize(request.getSize());
        Result result = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
        if (200 != result.getCode() || null == result.getData()) {
            return ResultUtil.error(ResultEnum.Err_1000);
        }
        return result;
    }

    @PostMapping(ExposeApiUrl.URL_ExposeApi_SsglRegionInfo)
    public Result regionInfo(@Validated @RequestBody RegionInfoRequest request) {
        SSGLReturnDto returnDto = new SSGLReturnDto();
        checkSign(request, request.getSvrId(), request.getComAppid(), DockApiCodeEnum.ssgl_regionInfo.getValue(), request.getSign(), returnDto);
        if (null != returnDto.getResultEnum()) {
            return ResultUtil.error(returnDto.getResultEnum());
        }

        JSONObject regionJsonObject = new JSONObject();
        regionJsonObject.put("comId", returnDto.getEntityComDockApi().getComId());
        Result result = accessService.getRegionInfo(regionJsonObject);
        if (200 != result.getCode() || null == result.getData()) {
            return ResultUtil.error(ResultEnum.Err_1000);
        }
        return result;
    }

    @PostMapping(ExposeApiUrl.URL_ExposeApi_SsglAccessAreaInfo)
    public Result accessAreaInfo(@Validated @RequestBody AccessAreaInfoRequest request) {
        SSGLReturnDto returnDto = new SSGLReturnDto();
        checkSign(request, request.getSvrId(), request.getComAppid(), DockApiCodeEnum.ssgl_accessAreaInfo.getValue(), request.getSign(), returnDto);
        if (null != returnDto.getResultEnum()) {
            return ResultUtil.error(returnDto.getResultEnum());
        }
        Map<String, Object> map = new HashMap<>();

        if (0 == request.getRegionId()) {
            JSONObject regionJsonObject = new JSONObject();
            regionJsonObject.put("comId", returnDto.getEntityComDockApi().getComId());
            Result getRegionInfo = accessService.getRegionInfo(regionJsonObject);
            if (200 == getRegionInfo.getCode()) {
                map.put("regionList", getRegionInfo.getData());
            }
        }

        Result getAreaInfo = accessService.GetAreaInfo(returnDto.getEntityComDockApi().getComId(), null, null, null);
        if (200 != getAreaInfo.getCode() || null == getAreaInfo.getData()) {
            return ResultUtil.error(ResultEnum.Err_1000);
        }
        map.put("areaList", getAreaInfo.getData());

        return ResultUtil.success(map);
    }

    @PostMapping(ExposeApiUrl.URL_ExposeApi_SsglNewPersonInfo)
    public Result ssglNewPersonInfo(@RequestBody SSGLNewPersonInfoRequest request) {
        String dockApiCode = DockApiCodeEnum.ssgl_newPersonInfo.getValue();
        Result apiParaResult = companyClientService.getApiPara(request.getComId(), dockApiCode);
        if (200 != apiParaResult.getCode()) {
            return ResultUtil.error(ResultEnum.Err_1000);
        }
        EntityComDockApi getApiPara = JSON.parseObject(JSON.toJSONString(apiParaResult.getData()), EntityComDockApi.class);
        StringBuilder apiPara = new StringBuilder();
        Integer personVer = 0;
        int limit = Integer.MAX_VALUE;
        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isNotBlank(getApiPara.getApiPara())) {

            map = JSON.parseObject(getApiPara.getApiPara(), HashMap.class);
            if (!StringUtils.isNumeric(map.get("personVer").toString())) {
                map.put("personVer", "0");
            }
            personVer = Integer.valueOf(map.get("personVer").toString());

        } else {
            initApiPara(apiPara, "0");
        }

        if (0 < request.getAutoSize()) {
            limit = request.getAutoSize();
        }

        try {
            Result personList = payHandleClientService.getComWhiteList(request.getComId(), personVer, limit);
            if (200 == personList.getCode()) {
                List<GetComWhiteListVo> getComWhiteListVos = JSON.parseArray(JSON.toJSONString(personList.getData()), GetComWhiteListVo.class);
                Optional<GetComWhiteListVo> getMaxId = getComWhiteListVos.stream().max(Comparator.comparing(GetComWhiteListVo::getId));
                if (getMaxId.isPresent()) {
                    Integer maxId = getMaxId.get().getId();
                    GetComRequestRequest getComRequestRequest = new GetComRequestRequest();
                    getComRequestRequest.setComId(request.getComId());
                    getComRequestRequest.setDockCode("ssgl");
                    getComRequestRequest.setDockApiCode(dockApiCode);
                    Result getComRequestResult = companyClientService.getComRequest(getComRequestRequest);
                    if (200 == getComRequestResult.getCode()) {
                        GetComRequestResponse getComRequestResponse = JSON.parseObject(JSON.toJSONString(getComRequestResult.getData()), GetComRequestResponse.class);
                        Map<String, Object> reqMap = new HashMap<>();
                        reqMap.put("comAppid", request.getComId());
                        reqMap.put("whiteList", getComWhiteListVos);
                        //TODO 发送post请求推送人员 【未测试】 第三方接口未开发
                        log.info("ssglNewPersonInfo==postsJson==reqMap=====参数：【{}】", reqMap);
                        String json = HttpUtils.postsJson(getComRequestResponse.getRequestUrl(), reqMap);
                        log.info("ssglNewPersonInfo==postsJson==json=====参数：【{}】",json);
                        Result results = JSON.parseObject(json, Result.class);
                        if (200 == results.getCode() || 0 == results.getCode() ) {
                            map.put("personVer", maxId);
                            apiPara = new StringBuilder(JSON.toJSONString(map));
                            companyClientService.setApiPara(request.getComId(), DockApiCodeEnum.ssgl_newPersonInfo.getValue(), apiPara.toString());
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.success();
    }


    @PostMapping(ExposeApiUrl.URL_ExposeApi_SsglAccessRecord)
    public Result ssglAccessRecord(@RequestBody SSGLAccessRecordRequest request) {
        try {

            Map<String, Object> reqMap = new HashMap<>();
            reqMap.put("comAppid", request.getComId());
            reqMap.put("areaId", request.getAreaId());
            reqMap.put("pId", request.getPId());
            reqMap.put("accessTime", request.getAccessTime());
            reqMap.put("openType", request.getOpenType());
            reqMap.put("deviceNo", request.getDeviceNo());
            reqMap.put("deviceName", request.getDeviceName());

            log.info("ssglAccessRecord==postsJson==reqMap=====参数：【{}】", reqMap);

            //TODO 发送post请求推记录 【未测试】 第三方接口未开发
            String json = HttpUtils.postsJson(request.getRequestUrl(), reqMap);
            log.info(json);
            log.info("ssglAccessRecord==postsJson==json=====参数：【{}】", json);

            Result results = JSON.parseObject(json, Result.class);
            log.info("ssglAccessRecord==postsJson==results=====参数：【{}】", results);

            if (200 == results.getCode() || 0 == results.getCode()) { //TODO
                SendAccessRecordRequest sendAccessRecordRequest = new SendAccessRecordRequest();
                sendAccessRecordRequest.setComId(request.getComId());
                sendAccessRecordRequest.setId(request.getId());
                sendAccessRecordRequest.setAreaId(request.getAreaId());
                sendAccessRecordRequest.setPId(request.getPId());
                sendAccessRecordRequest.setAccessTime(request.getAccessTime());
                sendAccessRecordRequest.setTarget(1);
                sendAccessRecordRequest.setMonthValue(request.getMonthValue());

                log.info("ssglAccessRecord==sendAccessRecord======参数：【{}】", sendAccessRecordRequest);

                mjrecodeClientService.sendAccessRecord(sendAccessRecordRequest);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(ResultEnum.Err_900);
        }

        return ResultUtil.success();
    }

    private void checkSign(Object request, String svrId, String comAppId, String dockApiCode, String requestSign, SSGLReturnDto returnDto) {
        try {
            EntityComDockApi entityComDockApi = getReplyApiPara(svrId, comAppId, dockApiCode, 0, returnDto);
            String sign = "";
            if (null != entityComDockApi) {
                sign = SignUtils.createSign(request, null, entityComDockApi.getKey());
                returnDto.setEntityComDockApi(entityComDockApi);
            }

            if (StringUtils.isBlank(sign)) {
                returnDto.setResultEnum(ResultEnum.Err_3100);
            } else if (!requestSign.equals(sign)) {
                returnDto.setResultEnum(ResultEnum.Err_202);
            } else if (4 > returnDto.getReturnCode()) {
                returnDto.setResultEnum(ResultEnum.Err_201);
            } else if (4 == returnDto.getReturnCode()) {
                returnDto.setResultEnum(ResultEnum.Err_204);
            } else if (200 != returnDto.getReturnCode()) {
                returnDto.setResultEnum(ResultEnum.Err_204);
            }

        } catch (Exception e) {
            if (null == returnDto.getReturnCode()) {
                returnDto.setResultEnum(ResultEnum.Err_1000);
            }
            e.printStackTrace();
        }

    }

    private EntityComDockApi getReplyApiPara(String svrId, String appId, String dockApiCode, Integer keyType, SSGLReturnDto returnDto) {
        GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
        getReplyApiParaRequest.setDockCode("ssgl");
        getReplyApiParaRequest.setDockApiCode(dockApiCode);
        getReplyApiParaRequest.setSvrAppid(svrId);
        getReplyApiParaRequest.setComAppid(appId);
        getReplyApiParaRequest.setKeyType(keyType);

        log.info("getReplyApiPara:" + getReplyApiParaRequest.toString());
        Result getReplyApiParaResult = companyClientService.getReplyApiPara(getReplyApiParaRequest);

        log.info("getReplyApiParaResult:" + getReplyApiParaResult.toString());
        if (getReplyApiParaResult.getCode() != 200) {
            returnDto.setReturnCode(getReplyApiParaResult.getCode());
            returnDto.setReturnMessage(getReplyApiParaResult.getMsg());
        }
        return JSON.parseObject(JSON.toJSONString(getReplyApiParaResult.getData()), EntityComDockApi.class);
    }

    private void initApiPara(StringBuilder apiPara, String personVer) {
        apiPara.append("{");
        apiPara.append("\"personVer\"");
        apiPara.append(":");
        apiPara.append("\"");
        apiPara.append(personVer);
        apiPara.append("\"");
        apiPara.append("}");

    }
}
